﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using NetFrameworkExtensions.Enterprise.Properties;

namespace NetFrameworkExtensions.Enterprise
{
  public abstract class ServiceManagerBase : IServiceManager
  {
    public IEnumerable<TService> GetAllInstances<TService>()
    {
      return GetAllInstances(typeof(TService)).Cast<TService>();
    }

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
      if (serviceType == null)
        throw new ArgumentNullException("serviceType");
      try
      {
        return DoGetAllInstances(serviceType);
      }
      catch (Exception ex)
      {
        throw new ServiceActivationException(FormatActivateAllExceptionMessage(ex, serviceType), ex);
      }
    }

    public TService GetInstance<TService>()
    {
      return (TService)GetInstance(typeof(TService), null);
    }

    public TService GetInstance<TService>(string key)
    {
      return (TService)GetInstance(typeof(TService), key);
    }

    public object GetInstance(Type serviceType)
    {
      return GetInstance(serviceType, null);
    }

    public object GetInstance(Type serviceType, string key)
    {
      if (serviceType == null)
        throw new ArgumentNullException("serviceType");
      try
      {
        return DoGetInstance(serviceType, key);
      }
      catch (Exception ex)
      {
        throw new ServiceActivationException(FormatActivationExceptionMessage(ex, serviceType, key), ex);
      }
    }

    public object GetService(Type serviceType)
    {
      return GetInstance(serviceType, null);
    }

    protected abstract IEnumerable<object> DoGetAllInstances(Type serviceType);
    protected abstract object DoGetInstance(Type serviceType, string key);
    protected virtual string FormatActivateAllExceptionMessage(Exception actualException, Type serviceType)
    {
      return FormattedResources.ActivateAllExceptionMessage(CultureInfo.CurrentUICulture, serviceType);
    }
    protected virtual string FormatActivationExceptionMessage(Exception actualException, Type serviceType, string key)
    {
      return FormattedResources.ActivationExceptionMessage(CultureInfo.CurrentUICulture, serviceType, key);
    }

  }
}
